如果我们提供了一个 sdk 给别人用,那么要把有哪些 api、都有什么参数等等信息写到文档中,并且每次改代码都要同步更新下文档。这件事情很繁琐,靠人来维护也不靠谱,可不可以自动生成呢?
api 文档的生成也是根据源码信息来的,有哪些函数、类、都有啥参数、参数是什么类型,这些都在源码里面,而更多信息一般都会写在注释里。我们可以通过 babel 取到这些信息,那么自然可以自动生成文档。
# 思路分析
比如这样一段代码:
/**
* say 你好
* @param name 名字
*/
function sayHi (name: string, age: number, a: boolean) {
console.log(`hi, ${name}`);
return `hi, ${name}`;
}
/**
* 类测试
*/
class Guang {
name: string; // name 属性
constructor(name: string) {
this.name = name;
}
/**
* 方法测试
*/
sayHi (): string {
return `hi, I'm ${this.name}`;
}
}
@前端进阶之旅: 代码已经复制到剪贴板
我们要处理 FunctionDeclaration 节点和 ClassDelcaration 节点:
FunctionDelcaration:
- 函数名: path.get(‘id’).toString()
- 参数: path.get(‘params’)
- 返回值类型: path.get(‘returnType’).getTypeAnnotation()
- 注释信息:path.node.leadingComments
注释可以使用 doctrine 来 parse,支持 @xxx 的解析
ClassDeclaration:
- 类名:path.get(‘id’).toString()
- 方法:travese ClassMethod 节点取信息(包括 constructor 和 method)
- 属性: traverse ClassProperty 节点取信息
- 注释信息: path.node.leadingComments
有了这些信息之后,就可以打印成文档了,打印就是拼接字符串的过程,可以支持 markdown、html、json 等格式。
我们来写下代码。
# 代码实现
首先搭一个插件的基本结构:
const { declare } = require('@babel/helper-plugin-utils');
const autoDocumentPlugin = declare((api, options, dirname) => {
api.assertVersion(7);
return {
pre(file) {
file.set('docs', []);
},
visitor: {
FunctionDeclaration(path, state) {
},
ClassDeclaration (path, state) {
}
},
post(file) {
const docs = file.get('docs');
}
}
}
@前端进阶之旅: 代码已经复制到剪贴板
我们在全局的 file 对象中放一个 docs 的数组,用于收集信息。
